package services;

import java.util.Collection;

import javax.transaction.Transactional;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import repositories.PurchasedItemRepository;
import domain.AvailableItem;
import domain.Customer;
import domain.Money;
import domain.Order;
import domain.PurchasedItem;
import domain.ShoppingCartItemUnit;
import forms.ItemForm;

@Service
@Transactional
public class PurchasedItemService {

	// Managed Repository
	@Autowired
	private PurchasedItemRepository purchasedItemRepository;

	// Supporting Services
	@Autowired
	private CustomerService customerService;

	public PurchasedItemService() {
		super();
	}

	// Simple CRUD methods

	public PurchasedItem create(ShoppingCartItemUnit ai, Order order) {
		PurchasedItem res;
		Money money;

		money = new Money();

		res = new PurchasedItem();

		res.setPrice(money);
		res.setReferenceNumber(ai.getAvailableItem().getReferenceNumber());
		res.setName(ai.getAvailableItem().getName());
		res.setDescription(ai.getAvailableItem().getDescription());
		res.setState(ai.getAvailableItem().getState());
		res.getPrice().setAmount(ai.getAvailableItem().getPrice().getAmount());
		res.getPrice().setCurrency(
				ai.getAvailableItem().getPrice().getCurrency());
		res.setPurchasedUnits(ai.getNumberOfItems());

		res.setOrder(order);
		res.setSeller(ai.getAvailableItem().getSeller());

		return res;
	}

	public PurchasedItem save(PurchasedItem purchasedItem) {
		Assert.notNull(purchasedItem);
		PurchasedItem res;
		Customer principal;

		principal = customerService.findByPrincipal();

		Assert.isTrue(purchasedItem.getOrder().getBuyer().equals(principal));
		res = purchasedItemRepository.save(purchasedItem);

		return res;
	}

	public PurchasedItem findOne(int purchasedItemId) {
		PurchasedItem res;

		res = purchasedItemRepository.findOne(purchasedItemId);

		return res;
	}

	public Collection<PurchasedItem> findAll() {
		Collection<PurchasedItem> result;
		result = purchasedItemRepository.findAll();
		return result;
	}

	// Other Business methods

	public Collection<PurchasedItem> findPurchasedItemsBySellerId() {
		Collection<PurchasedItem> result;
		Customer seller;

		seller = customerService.findByPrincipal();

		result = purchasedItemRepository.findPurchasedItemsBySellerId(seller
				.getId());

		return result;
	}

	public Collection<PurchasedItem> findByOrder(Order order) {
		Assert.notNull(order);
		Collection<PurchasedItem> result;

		result = purchasedItemRepository.findByOrderId(order.getId());

		return result;
	}

	public Collection<PurchasedItem> findPurchasedItemsByBuyerId() {
		Collection<PurchasedItem> result;
		Customer buyer;

		buyer = customerService.findByPrincipal();

		result = purchasedItemRepository.findPurchasedItemsByBuyerId(buyer
				.getId());

		return result;
	}

	public Collection<PurchasedItem> findPurchasedItemIdByAvailableItemRefNumber(
			String refNumber) {
		Collection<PurchasedItem> result;
		Customer principal;
		principal = customerService.findByPrincipal();
		Assert.isTrue(principal instanceof Customer);

		result = purchasedItemRepository
				.findPurchasedItemIdByAvilableItemRefNumber(refNumber);
		return result;
	}

	// Form methods

	public ItemForm purchasedItemToForm(PurchasedItem ai) {
		ItemForm res;

		res = new ItemForm();

		res.setItemId(ai.getId());

		res.setReferenceNumber(ai.getReferenceNumber());
		res.setName(ai.getName());
		res.setDescription(ai.getDescription());
		res.setState(ai.getState());
		res.setAmount(ai.getPrice().getAmount());
		res.setCurrency(ai.getPrice().getCurrency());
		res.setPurchasedUnits(ai.getPurchasedUnits());

		res.setSeller(ai.getSeller());

		res.setAvailableUnits(0);

		return res;
	}

	public PurchasedItem reconstruct(ItemForm itf) {
		PurchasedItem res;

		res = findOne(itf.getItemId());

		return res;
	}

	public Boolean isBuyer(AvailableItem availableItem) {
		Boolean result;
		Customer principal;
		Assert.notNull(availableItem);
		Collection<String> refNumbersOfPurchasedItems;

		result = false;
		principal = customerService.findByPrincipal();
		String referenceNumber = availableItem.getReferenceNumber();
		refNumbersOfPurchasedItems = purchasedItemRepository
				.findRefNumbersOfMyPurchasedItems(principal.getId());

		if (refNumbersOfPurchasedItems.contains(referenceNumber)) {
			result = true;
		}

		return result;

	}

}
